/*************************************************************************************************
 * Class to represent a factory of geometric elements
 *************************************************************************************************/

package geometricElement;
import java.util.HashMap;

public class GeoElementsFactory {
	
	// interface of object factory
	private interface ObjectFac {
		public GeometricElement create(int xCord, int yCord, double property);
	}	
	// circle factory
	private class CircleFac implements ObjectFac {
			public GeometricElement create(int xCord, int yCord, double radius) { return new Circle(xCord, yCord, radius); }
	}
	// square factory
	private class SquareFac implements ObjectFac {
		public GeometricElement create(int xCord, int yCord, double length) { return new Square(xCord, yCord, length); }
	}
	// perfect triangle factory
	private class PerfectTriangleFac implements ObjectFac {
		public GeometricElement create(int xCord, int yCord, double length) { return new PerfectTriangle(xCord, yCord, length); }
	}

	// members	
	private HashMap<String, ObjectFac> objectFactory; // factory for all geometric elements

	// methods
	/**
	 * Constructor. Creates a new geometric elements factory- a key is a string holding
     * element's name and the value is the matching factory
	 */
	public GeoElementsFactory() {
		objectFactory = new HashMap<String, ObjectFac> ();
		objectFactory.put("Circle", new CircleFac());
		objectFactory.put("Square", new SquareFac());
		objectFactory.put("PerfectTriangle", new PerfectTriangleFac());
	}

	/**
	 * Uses given type string in order to find suitable factory in the hash table.
	 * Then calls its create method with given shape property.
	 * If given key is not in the hash table, NullPointerException is thrown
	 * @param type- type of geometric element to create
	 * @param xCord- x-axis coordinate of new geometric element
	 * @param yCord- y-axis coordinate of new geometric element
	 * @param property- property of new geometric element
	 * @return A new geometric element of matching type with given details
	 * @throws TypeNotExistException- thrown if given type does not match any known geometric element
	 */
	public GeometricElement createElement(String type, int xCord, int yCord, double property) throws TypeNotExistException {
		try { // try creating a new element with given details
			return objectFactory.get(type).create(xCord, yCord, property);			
		} catch (NullPointerException exception) {
			// given type does not exist
			throw new TypeNotExistException(type);
		}
	}
}